package net.sh.dpinfrastructure.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.UUID;

/**
 * 
 * 常用方法
 * 
 * @author Lancer
 * @date 2015年8月29日下午3:23:45
 *
 */
public final class DPCommonUtils {

    private final static char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c',
            'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
            'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
            'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};

    private DPCommonUtils() {}
    
    /**
     * 
     * 序列化对象
     *
     * @param object
     * @return
     * 
     * @author shaohui
     * @date 2015年10月29日 下午1:21:12
     */
    public static byte[] serialize(Serializable object) {
        if (object == null) {
            throw new NullPointerException();
        }
        ObjectOutputStream oos = null;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] result = null;
        try {
            oos = new ObjectOutputStream(baos);
            oos.writeObject(object);
            result = baos.toByteArray();
        } catch (IOException e) {}
        return result;
    }
    
    
    /**
     * 
     * 反序列化
     *
     * @param objBytes 对象字节数组
     * @param clazz
     * @return
     * 
     * @author shaohui
     * @date 2015年10月29日 下午1:46:58
     */
    @SuppressWarnings("unchecked")
    public static <T extends Serializable> T unserialize(byte[] objBytes, Class<T> clazz) {
        if (objBytes == null || clazz == null) {
            throw new NullPointerException();
        }
        ObjectInputStream ois = null;
        ByteArrayInputStream bais = new ByteArrayInputStream(objBytes);
        T result = null;
        try {
            ois = new ObjectInputStream(bais);
            result = (T) (ois.readObject());
        } catch (Exception e) {}
        return result;
    }
    
    /**
     * 
     * 获取19位UUID
     *
     * @return
     * 
     * @author shaohui
     * @date 2015年9月10日 下午1:18:07
     */
    public static String getShortUUID() {
        UUID uuid = UUID.randomUUID();  
        StringBuilder sb = new StringBuilder();  
        sb.append(digits(uuid.getMostSignificantBits() >> 32, 8));  
        sb.append(digits(uuid.getMostSignificantBits() >> 16, 4));  
        sb.append(digits(uuid.getMostSignificantBits(), 4));  
        sb.append(digits(uuid.getLeastSignificantBits() >> 48, 4));  
        sb.append(digits(uuid.getLeastSignificantBits(), 12));  
        return sb.toString();  
    }

    /**
     * 
     * 长整型以62进制字符串输出
     *
     * @param num
     * @return
     * 
     * @author shaohui
     * @date 2015年9月10日 下午1:14:33
     */
    public static String numTo62SystemString(long num) {
        final int size = 65;  
        int charPos = 64;  
  
        char[] buf = new char[size];  
        boolean negative = (num < 0);  
  
        if (!negative) {  
            num = -num;  
        }  
  
        while (num <= -62) {  
            buf[charPos--] = digits[(int) (-(num % 62))];  
            num = num / 62;  
        }  
        buf[charPos] = digits[(int) (-num)];  
  
        if (negative) {  
            buf[--charPos] = '-';  
        }  
  
        return new String(buf, charPos, (size - charPos));  
    }
    
    /**
     * 
     * 方法描述 TODO
     *
     * @param val
     * @param digits
     * @return
     * 
     * @author shaohui
     * @date 2015年10月29日 下午1:16:34
     */
    private static String digits(long val, int digits) {  
        long hi = 1L << (digits * 4);  
        return numTo62SystemString(hi | (val & (hi - 1)))  
                .substring(1);  
    }  
    
}
